home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / language / dino / dino_bot.1 / source / shell / cmdline.c next >
Encoding:
C/C++ Source or Header  |  1991-05-14  |  89.8 KB  |  2,350 lines

  1. /* Copyright, 1990, Regents of the University of Colorado */
  2. #define BOOL char
  3. #define TRUE 1
  4. #define FALSE 0
  5. #define MAXINCLUDE 11
  6. #define MAXMACHINES 10
  7. #define MAXMACHNAME 20
  8. #define MAXDIM 50
  9. #define OPTIONSIZE 50
  10. #define LINESIZE 256
  11. #define NAMESIZE 15
  12.  
  13. #include <stdio.h>
  14. #include <string.h>
  15. #include <varargs.h>
  16. #include <sys/types.h>
  17. #include <sys/param.h>
  18. #include <sys/stat.h>
  19. #include <pwd.h>
  20. #include <ctype.h>
  21. #include "../inc/version.h"
  22.  
  23. static BOOL numcheck();
  24. static void error();
  25. static void message();
  26. static void dmessage();
  27. static void cmdlnparse();
  28. static void addbools();
  29. static void sh_message();
  30.  
  31. static BOOL QUIET = FALSE;
  32. static BOOL ALADIN = FALSE;
  33. static BOOL COMMENTS = FALSE;
  34. static BOOL ORDER = FALSE;
  35. static BOOL NUMBERS = FALSE;
  36. static BOOL NOTES = FALSE;
  37. static BOOL WARNINGS = FALSE;
  38. static BOOL SUFFIX_MODEL = TRUE;
  39. static BOOL header = FALSE;
  40. static BOOL MODEL = FALSE;
  41.  
  42. static char TYPE;
  43. static char SERIES;
  44. static char DIRECTORY[MAXPATHLEN] = {0};
  45. static char SUFFIX[25] = {0};
  46. static char INCLUDE[MAXINCLUDE][MAXPATHLEN];
  47. static char SOURCE[MAXPATHLEN] = {0};
  48. static char USER[NAMESIZE] = {0};
  49.  
  50. static int NINC = 0;
  51. static int CUBEDIM = 0;
  52. static long int BUFSIZE = 0;
  53. static long int LASTTYPE = 0;
  54. static long int FIRSTTYPE = 0;
  55. static int PARTIAL = 3;
  56.  
  57. static struct {
  58.                 char name[MAXMACHNAME];
  59.                 char suffix[MAXMACHNAME + 2];
  60.                 char address[MAXPATHLEN];
  61.                 char user[NAMESIZE];
  62.                 char directory[MAXPATHLEN];
  63.                 char rdirectory[MAXPATHLEN];
  64.                 int type;
  65.                 int maxdim;
  66.                 int dim;
  67.                 BOOL rcp;
  68.                 BOOL rsh;
  69.                 char run;
  70.                 BOOL date;
  71.                 BOOL lcl_here;
  72.               } machines[MAXMACHINES];
  73.  
  74. static int nummach = 0;
  75. static int default_mach = 0;
  76. static BOOL macherr = FALSE;
  77.  
  78. extern void exit();
  79. extern long int strtol();
  80. extern char *getenv();
  81.  
  82. main(argc, argv)
  83.     int argc;
  84.     char *argv[];
  85.    {
  86.     char ROOT[MAXPATHLEN];
  87.  
  88.     int I, J, K, L, M;
  89.     char cmdln[OPTIONSIZE];
  90.     char *temp, *temp2, *home;
  91.     int test;
  92.     char varname[MAXMACHNAME + 6];
  93.     char username[25];
  94.     BOOL used;
  95.     BOOL special = FALSE;
  96.     char tempdir[MAXPATHLEN];
  97.     char OUTLINE[LINESIZE];
  98.     int mask;
  99.  
  100.     struct stat buf1;
  101.     struct passwd *pwbuf;
  102.  
  103.         /* Get the default environment parameters
  104.             (These are set in the script that calls this program.)       */
  105.  
  106.         /* The first of these is the list of machines that are defined
  107.             on this system. These (and their characteristics) should be
  108.             defined in the environment variable "Dmachs".                */
  109.  
  110.     if ((temp = getenv("Dmachs")) == NULL)
  111.        {
  112.             /* If there is no such variable,
  113.                         set the following default parameters: */
  114.  
  115.         macherr = TRUE;
  116.         PARTIAL = 0;
  117.         MODEL = TRUE;
  118.         TYPE = 'c';
  119.         SERIES = '2';
  120.         CUBEDIM = 4;
  121.        }
  122.     else
  123.        {
  124.             /* Otherwise, check to see if Dmachs is empty: */
  125.  
  126.         if (temp[0] == '\0')
  127.             error(1, "\tEmpty Dmachs environment string found.\n\n");
  128.         J = 0;
  129.         for (I = 0; I < MAXMACHINES; I++)
  130.            {
  131.                 /* If it is not, for each machine defined in the variable: */
  132.  
  133.                     /* Read the name. */
  134.  
  135.             for (; temp[J] == ' ' || temp[J] == '\t' || temp[J] == '\n'; J++);
  136.             for (K = 0; temp[J] != ' ' && temp[J] != '\0' &&
  137.                         temp[J] != '\t' && temp[J] != '\n'; J++, K++)
  138.                machines[I].name[K] = temp[J];
  139.             machines[I].name[K] = '\0';
  140.  
  141.                     /* Read the address. */
  142.  
  143.             for (; temp[J] == ' ' || temp[J] == '\t' || temp[J] == '\n'; J++);
  144.             for (K = 0; temp[J] != ' ' && temp[J] != '\0' &&
  145.                         temp[J] != '\t' && temp[J] != '\n'; J++, K++)
  146.                machines[I].address[K] = temp[J];
  147.             machines[I].address[K] = '\0';
  148.  
  149.                     /* Read the user code. */
  150.  
  151.             for (; temp[J] == ' ' || temp[J] == '\t' || temp[J] == '\n'; J++);
  152.             for (K = 0; temp[J] != ' ' && temp[J] != '\0' &&
  153.                         temp[J] != '\t' && temp[J] != '\n'; J++, K++)
  154.                machines[I].user[K] = temp[J];
  155.             machines[I].user[K] = '\0';
  156.  
  157.                     /* Read the directory code. */
  158.  
  159.             for (; temp[J] == ' ' || temp[J] == '\t' || temp[J] == '\n'; J++);
  160.             for (K = 0; temp[J] != ' ' && temp[J] != '\0' &&
  161.                         temp[J] != '\t' && temp[J] != '\n'; J++, K++)
  162.                machines[I].directory[K] = temp[J];
  163.             machines[I].directory[K] = '\0';
  164.  
  165.                     /* Get the machine type and check that it is correct. */
  166.  
  167.             for (; temp[J] == ' ' || temp[J] == '\t' || temp[J] == '\n'; J++);
  168.             switch (temp[J++])
  169.                {
  170.                 case 's' :
  171.                     machines[I].type = 5;
  172.                     break;
  173.                 case 'S' :
  174.                     machines[I].type = 6;
  175.                     break;
  176.                 case '1' :
  177.                     machines[I].type = 1;
  178.                     break;
  179.                 case '2' :
  180.                     machines[I].type = 2;
  181.                     break;
  182.                 case '8' :
  183.                     machines[I].type = 3;
  184.                     break;
  185.                 case 'G' :
  186.                     machines[I].type = 4;
  187.                     break;
  188.                 default:
  189.                     error(0, "\tInvalid machine type for %s in Dmachs.\n",
  190.                                                             machines[I].name);
  191.                }
  192.  
  193.                     /* Get the maximum number of dimensions for this
  194.                         machine and check this against the defined maximum. */
  195.  
  196.             if ((machines[I].maxdim =
  197.                     (int) strtol(&(temp[J++]), (char **) NULL, 0)) < 1 ||
  198.                                                       machines[I].maxdim > MAXDIM)
  199.  
  200.                 error(0, "\tInvalid max dimension (%d) for %s in Dmachs.\n",
  201.                                            machines[I].maxdim, machines[I].name);
  202.  
  203.                     /* Get the value of the Rcp switch
  204.                                             and check it for validity. */
  205.  
  206.             for (; isdigit(temp[J]); J++);
  207.             switch (temp[J++])
  208.                {
  209.                 case 'T' :
  210.                     machines[I].rcp = TRUE;
  211.                     break;
  212.                 case 'F' :
  213.                     machines[I].rcp = FALSE;
  214.                     break;
  215.                 default:
  216.                     error(0,
  217.                          "\tInvalid remote copy option for %s in Dmachs.\n",
  218.                                                             machines[I].name);
  219.                }
  220.  
  221.                     /* Get the value of the Rsh switch
  222.                                             and check it for validity. */
  223.  
  224.            switch (temp[J++])
  225.                {
  226.                 case 'T' :
  227.                     machines[I].rsh = TRUE;
  228.                     break;
  229.                 case 'F' :
  230.                     machines[I].rsh = FALSE;
  231.                     break;
  232.                 default:
  233.                     error(0,
  234.                           "\tInvalid dino2 option for %s in Dmachs.\n",
  235.                                                             machines[I].name);
  236.                }
  237.  
  238.                     /* Get the value of the Run switch
  239.                                             and check it for validity. */
  240.  
  241.             switch (temp[J++])
  242.                {
  243.                 case 'T' :
  244.                     machines[I].run = 'T';
  245.                     break;
  246.                 case 'F' :
  247.                     machines[I].run = 'F';
  248.                     break;
  249.                 case 'S' :
  250.                     machines[I].run = 'S';
  251.                     break;
  252.                 default:
  253.                     error(0,
  254.                       "\tInvalid execution option for %s in Dmachs.\n",
  255.                                                             machines[I].name);
  256.                }
  257.  
  258.                     /* Get the value of the Date switch
  259.                                             and check it for validity. */
  260.  
  261.             switch (temp[J++])
  262.                {
  263.                 case 'T' :
  264.                     machines[I].date = TRUE;
  265.                     break;
  266.                 case 'F' :
  267.                     machines[I].date = FALSE;
  268.                     break;
  269.                 default:
  270.                     error(0,
  271.                        "\tInvalid remote copy option for %s in Dmachs.\n",
  272.                                                             machines[I].name);
  273.                }
  274.  
  275.                     /* Get the default number of dimensions
  276.                                             and check that for validity. */
  277.  
  278.             if ((machines[I].dim =
  279.                     (int) strtol(&(temp[J++]), (char **) NULL, 0)) < 1 ||
  280.                                             machines[I].dim > machines[I].maxdim)
  281.                 error(0, "\tInvalid default dimension (%d) for %s in Dmachs.\n",
  282.                                               machines[I].dim, machines[I].name);
  283.  
  284.                     /* Do some clean-up at the end
  285.                                     of the descriptor for this machine. */
  286.  
  287.             for (; isdigit(temp[J]); J++);
  288.             nummach++;
  289.             if (temp[J] != ' ' && temp[J] != '\t' &&
  290.                                             temp[J] != '\0' && temp[J] != '\n')
  291.                 error(0, "\tInvalid descriptor for %s in Dmachs.\n",
  292.                                                             machines[I].name);
  293.  
  294.                     /* Now, we will check that the descriptors for
  295.                             this machine are consistant with each other
  296.                             (OK, we will also do some processing so we
  297.                                         can use the information later): */
  298.  
  299.             if (machines[I].address[0] == '.')
  300.                {
  301.                         /* Insure that an address of "."
  302.                                     has no additional characters. */
  303.  
  304.                 if (machines[I].run == 'T' && machines[I].address[1] != '\0')
  305.                     error(0, "\tInvalid address (%s) for %s in Dmachs.\n",
  306.                                            machines[I].address, machines[I].name);
  307.  
  308.                         /* Check to see that there is not a
  309.                             local address then an "rcp" to copy files. */
  310.  
  311.                 if (machines[I].run == 'T' && machines[I].rcp)
  312.                     error(0,
  313.             "\tAddress (.) for %s in Dmachs is inconsistant with rcp option.\n",
  314.                                                             machines[I].name);
  315.  
  316.                         /* Check to see that there is not a local address
  317.                         then an "rsh" to execute the backend of the compiler. */
  318.  
  319.                 if (machines[I].run == 'T' && machines[I].rsh)
  320.                     error(0,
  321.             "\tAddress (.) for %s in Dmachs is inconsistant with rsh option.\n",
  322.                                                             machines[I].name);
  323.               }
  324.             else
  325.  
  326.                         /* Check to see that there is not a remote address
  327.                         then no "rsh" to execute the backend of the compiler. */
  328.  
  329.                 if (machines[I].run == 'T' && ! machines[I].rsh)
  330.                     error(0,
  331. "\tAddress (%s) for %s in Dmachs is inconsistant with rsh option.\n\t\tA local machine must have an address of \".\"\n",
  332.                                         machines[I].address, machines[I].name);
  333.  
  334.             if (machines[I].user[0] == '~')
  335.                {
  336.                         /* Insure that an user of "~"
  337.                                     has no additional characters. */
  338.  
  339.                 if (machines[I].user[1] != '\0')
  340.                     error(0, "\tInvalid user (%s) for %s in Dmachs.\n",
  341.                                            machines[I].user, machines[I].name);
  342.                }
  343.             else
  344.                {
  345.                         /* Insure that the user is not ".". */
  346.  
  347.                 if (machines[I].user[0] == '.')
  348.                     error(0, "\tInvalid user (%s) for %s in Dmachs.\n",
  349.                                            machines[I].user, machines[I].name);
  350.  
  351.                         /* Check to see that if this is not a remote machine
  352.                         then the user for the back end is the current user. */
  353.  
  354.                 if (machines[I].run == 'T' && ! machines[I].rsh)
  355.                     error(0,
  356.               "\tInvalid user (%s) for %s in Dmachs on local machine\n",
  357.                                         machines[I].user, machines[I].name);
  358.                }
  359.  
  360.             machines[I].lcl_here = FALSE;
  361.  
  362.             switch (machines[I].directory[0])
  363.                {
  364.                 case '.':
  365.  
  366.                         /* Check to see if this is a remote machine that
  367.                             requires an "rcp" to get the files there, that
  368.                             the default directory for the remote machine
  369.                                             is not the current directory. */
  370.  
  371.                     if (machines[I].run == 'T' && machines[I].rcp)
  372.                         error(0,
  373.                  "\tInvalid directory (%s) for remote machine %s in Dmachs.\n",
  374.                                     machines[I].directory, machines[I].name);
  375.  
  376.                         /* If the current directory is the default, put
  377.                         in the actual name of the directory instead of "." */
  378.  
  379.                     (void) strcpy(tempdir, machines[I].directory);
  380.                     (void) strcpy(machines[I].directory, getenv("PWD"));
  381.                     if (tempdir[1] != '\0')
  382.                        {
  383.  
  384.                         /* If there is more than just ".",
  385.                                     make sure it is a sub-directory. */
  386.  
  387.                         if (tempdir[1] != '/')
  388.                             error(0,
  389.                  "\tInvalid directory (%s) for remote machine %s in Dmachs.\n",
  390.                                      machines[I].directory, machines[I].name);
  391.                         (void) strcat(machines[I].directory, &(tempdir[1]));
  392.                        }
  393.                     else
  394.  
  395.                         /* If it is actually this directory,
  396.                                         set a flag so we know that later. */
  397.  
  398.                         machines[I].lcl_here = TRUE;
  399.  
  400.                         /* If we are going to execute on a remote machine,
  401.                             construct an abbreviated directory name for it. */
  402.  
  403.                     if (machines[I].rsh)
  404.                        {
  405.                         home = getenv("HOME");
  406.                         for (L = 0; home[L] != '\0' &&
  407.                                         home[L] == machines[I].directory[L]; L++);
  408.                         M = 0;
  409.                         if (machines[I].directory[L] != '\0')
  410.                             for (L++; machines[I].directory[L] != '\0'; L++, M++)
  411.                                 machines[I].rdirectory[M] = machines[I].directory[L];
  412.                         machines[I].rdirectory[M] = '\0';
  413.                        }
  414.                     break;
  415.                 case '~':
  416.                     if (machines[I].run == 'T')
  417.                        {
  418.                         if (machines[I].rcp)
  419.                            {
  420.                 
  421.                         /* If we use an "rcp" to get the files to the
  422.                                remote machine, strip the "~" or "~/" out. */
  423.                 
  424.                             if (machines[I].directory[1] == '\0')
  425.                                 machines[I].directory[0] = '\0';
  426.                             else
  427.                                 if (machines[I].directory[1] == '/')
  428.                                     for (L = 0;
  429.                                             machines[I].directory[L] != '\0'; L++)
  430.                                         machines[I].directory[L] =
  431.                                                 machines[I].directory[L+2];
  432.                             strcpy(machines[I].rdirectory, machines[I].directory);
  433.                            }
  434.                         else
  435.                            {
  436.                 
  437.                         /* If we don't use an "rcp": */
  438.  
  439.                         /* If we do use an "rsh",  first put the appropriate
  440.                             relative directory in the remote ditrectory. */
  441.                 
  442.                             if (machines[I].directory[1] == '\0')
  443.                                 machines[I].rdirectory[0] = '\0';
  444.                             else
  445.                                 if (machines[I].directory[1] == '/')
  446.                                     (void) strcpy(machines[I].rdirectory,
  447.                                                     &(machines[I].directory[2]));
  448.  
  449.                                 /* In any case,  get the complete pathname for
  450.                                     the local directory instead of "~". */
  451.  
  452.                             (void) strcpy(tempdir, machines[I].directory);
  453.                             if (tempdir[1] == '\0' || tempdir[1] == '/')
  454.                                {
  455.                                 (void) strcpy(machines[I].directory, getenv("HOME"));
  456.                                 if (tempdir[1] == '/')
  457.                                     (void) strcat(machines[I].directory,
  458.                                                 &(tempdir[1]));
  459.                                }
  460.                             else
  461.                                {
  462.                 
  463.                          /* While we are doing this, if a user other than
  464.                                 the current user is specified, check to be
  465.                                                                 sure it exists. */
  466.                 
  467.                             for (L = 1; tempdir[L] != '/' &&
  468.                                          tempdir[L] != '\0'; L++);
  469.                             (void) strncpy(username, &(tempdir[1]), L - 1);
  470.                             username[L-1] = '\0';
  471.                             if ((pwbuf = getpwnam(username)) == NULL)
  472.                                 error(0,
  473.                           "\tInvalid directory (%s) for %s in Dmachs, no login for %s\n",
  474.                               machines[I].directory, machines[I].name, username);
  475.                             (void) strcpy(machines[I].directory, pwbuf->pw_dir);
  476.                             if (tempdir[L] != '\0')
  477.                                 (void) strcat(machines[I].directory,
  478.                                                 &(tempdir[L]));
  479.                                }
  480.                            }
  481.                        }
  482.                     break;
  483.                 default:
  484.                     if (machines[I].rsh)
  485.                         (void) strcpy(machines[I].rdirectory, machines[I].directory);
  486.                }
  487.             for (; temp[J] == ' ' || temp[J] == '\t' || temp[J] == '\n'; J++);
  488.             if (temp[J] == '\0')
  489.                 break;
  490.            }
  491.         if (I == MAXMACHINES)
  492.             error(0,
  493.                 "\tMaximum number of allowable machines exceeded in Dmachs\n");
  494.        }
  495.  
  496.     if ((temp = getenv("sDmachine")) == NULL)
  497.         default_mach = 0;
  498.     else
  499.        {
  500.         for (I = 0; I < nummach; I++)
  501.             if (strcmp(temp, machines[I].name) == 0)
  502.                {
  503.                 default_mach = I;
  504.                 break;
  505.                }
  506.         if (I == nummach)
  507.     error(0, "\tSystem default machine (sDmachine = %s) not found in Dmachs.\n",
  508.                                                                         temp);
  509.        }
  510.  
  511.     for (I = 0; I < nummach; I++)
  512.        {
  513.         (void) sprintf(varname, "sD%ssuf", machines[I].name);
  514.         if ((temp = getenv(varname)) != NULL)
  515.             (void) strcpy(machines[I].suffix, temp);
  516.         else
  517.             (void) strcpy(machines[I].suffix, machines[I].name);
  518.        }
  519.  
  520.     if ((temp = getenv("Dmachine")) != NULL)
  521.        {
  522.         for (I = 0; I < nummach; I++)
  523.             if (strcmp(temp, machines[I].name) == 0)
  524.                {
  525.                 default_mach = I;
  526.                 break;
  527.                }
  528.         if (I == nummach)
  529. error(0, "\tUser default machine (Dmachine = %s) not defined in system list.\n",
  530.                                                                         temp);
  531.        }
  532.  
  533.     for (I = 0; I < nummach; I++)
  534.        {
  535.         (void) sprintf(varname, "D%ssize", machines[I].name);
  536.         if ((temp = getenv(varname)) != NULL)
  537.             if ((test = strtol(temp, (char **) NULL, 0)) > 0 &&
  538.                                                 test < machines[I].maxdim + 1)
  539.                 machines[I].dim = test;
  540.             else
  541.                 error(0, "\tInvalid user default size (D%ssize = %d) for %s.\n",
  542.                                     machines[I].name, test, machines[I].name);
  543.        }
  544.  
  545.     for (I = 0; I < nummach; I++)
  546.        {
  547.         (void) sprintf(varname, "D%ssuf", machines[I].name);
  548.         if ((temp = getenv(varname)) != NULL)
  549.             (void) strcpy(machines[I].suffix, temp);
  550.        }
  551.  
  552.     for (I = 0; I < nummach; I++)
  553.        {
  554.         (void) sprintf(varname, "D%sdir", machines[I].name);
  555.         if ((temp = getenv(varname)) != NULL)
  556.            {
  557.             machines[I].lcl_here = FALSE;
  558.             if (temp[0] != '/' && temp[0] != '.' && temp[0] != '~')
  559.                {
  560.                 if (machines[I].directory[0] == '\0')
  561.                     (void) strcpy(machines[I].directory, temp);
  562.                 else
  563.                    {
  564.                     (void) strcat(machines[I].directory, "/");
  565.                     (void) strcat(machines[I].directory, temp);
  566.                    }
  567.                 if (machines[I].rdirectory[0] == '\0')
  568.                     (void) strcpy(machines[I].rdirectory, temp);
  569.                 else
  570.                    {
  571.                     (void) strcat(machines[I].rdirectory, "/");
  572.                     (void) strcat(machines[I].rdirectory, temp);
  573.                    }
  574.                }
  575.             else
  576.                {
  577.                 switch (temp[0])
  578.                    {
  579.                     case '.':
  580.                         if (machines[I].rcp)
  581.                             error(0,
  582.                     "\tInvalid directory (%s) for remote machine %s in %s\n",
  583.                                         temp, machines[I].name, varname);
  584.                         (void) strcpy(machines[I].directory, getenv("PWD"));
  585.                         if (temp[1] != '\0')
  586.                            {
  587.                             if (temp[1] != '/')
  588.                                 error(0,
  589.                     "\tInvalid directory (%s) for remote machine %s in %s\n",
  590.                                             temp, machines[I].name, varname);
  591.                             (void) strcat(machines[I].directory, &(temp[1]));
  592.                            }
  593.                         else
  594.                             machines[I].lcl_here = TRUE;
  595.                     if (machines[I].rsh)
  596.                        {
  597.                         home = getenv("HOME");
  598.                         for (J = 0; home[J] != '\0' &&
  599.                                         home[J] == machines[I].directory[J]; J++);
  600.                         M = 0;
  601.                         if (machines[I].directory[J] != '\0')
  602.                             for (J++; machines[I].directory[J] != '\0'; J++, M++)
  603.                                 machines[I].rdirectory[M] = machines[I].directory[J];
  604.                         machines[I].rdirectory[M] = '\0';
  605.                        }
  606.                         break;
  607.                     case '~':
  608.                         if (machines[I].rcp)
  609.                            {
  610.                             if (temp[1] == '\0')
  611.                                 machines[I].directory[0] = '\0';
  612.                             else
  613.                                 if (temp[1] == '/')
  614.                                     for (J = 0; temp[J] != '\0'; J++)
  615.                                         machines[I].directory[J] = temp[J+2];
  616.                              strcpy(machines[I].rdirectory, machines[I].directory);
  617.                            }
  618.                         else
  619.                            {
  620.                             if (temp[1] == '\0')
  621.                                 machines[I].rdirectory[0] = '\0';
  622.                             else
  623.                                 if (temp[1] == '/')
  624.                                     (void) strcpy(machines[I].rdirectory,
  625.                                                     &(temp[2]));
  626.  
  627.                             if (temp[1] == '\0' || temp[1] == '/')
  628.                                {
  629.                                 (void) strcpy(machines[I].directory,
  630.                                                             getenv("HOME"));
  631.                                 if (temp[1] == '/')
  632.                                     (void) strcat(machines[I].directory,
  633.                                                                 &(temp[1]));
  634.                                }
  635.                             else
  636.                                {
  637.                                 for (J = 1; temp[J] != '/' &&
  638.                                                        temp[J] != '\0'; J++);
  639.                                 (void) strncpy(username, &(temp[1]), J - 1);
  640.                                 username[J-1] = '\0';
  641.                                 if ((pwbuf = getpwnam(username)) == NULL)
  642.                                     error(0,
  643.         "\tInvalid directory (%s) for %s specified in %s, no login for %s\n",
  644.                                         temp, machines[I].name, username);
  645.                                 (void) strcpy(machines[I].directory,
  646.                                                             pwbuf->pw_dir);
  647.                                 if (tempdir[J] != '\0')
  648.                                     (void) strcat(machines[I].directory,
  649.                                                                 &(temp[J]));
  650.                                }
  651.                            }
  652.                         break;
  653.                    }
  654.                }
  655.            }
  656.        }
  657.  
  658.     for (I = 0; I < nummach; I++)
  659.        {
  660.         (void) sprintf(varname, "D%susr", machines[I].name);
  661.         if ((temp = getenv(varname)) != NULL)
  662.            {
  663.             (void) strcpy(machines[I].user, temp);
  664.             if (machines[I].user[0] == '~')
  665.                {
  666.                 if (machines[I].user[1] != '\0')
  667.                     error(0, "\tInvalid user for %s in %s.\n",
  668.                                                    machines[I].name, varname);
  669.                }
  670.             else
  671.                {
  672.                 if (machines[I].user[0] == '.')
  673.                     error(0, "\tInvalid user (%s) for %s in %s\n",
  674.                                   machines[I].user, machines[I].name, varname);
  675.                 if (! machines[I].rsh)
  676.                     error(0,
  677.               "\tInvalid user (%s) for %s in %s\n",
  678.                                  machines[I].user, machines[I].name, varname);
  679.                }
  680.            }
  681.        }
  682.  
  683.     cmdlnparse(argc, argv, cmdln);
  684.     (void) sprintf(varname, "sD%sopt", machines[default_mach].name);
  685.     if ((temp = getenv(varname)) != NULL)
  686.         addbools(temp, TRUE);
  687.     (void) sprintf(varname, "D%sopt", machines[default_mach].name);
  688.     if ((temp = getenv(varname)) != NULL)
  689.         addbools(temp, FALSE);
  690.     addbools(cmdln, FALSE);
  691.  
  692.     if ((temp = getenv("Dinc")) != NULL)
  693.        {
  694.         J = 0;
  695.         do
  696.            {
  697.             for (; temp[J] == ' ' || temp[J] == '\t' ||
  698.                                                     temp[J] == '\n'; J++);
  699.             for (K = J; temp[K] != ' ' && temp[K] != '\t' &&
  700.                                 temp[K] != '\n' && temp[K] != '\0'; K++);
  701.             if (temp[J] != '\0')
  702.                {
  703.                 if (NINC < MAXINCLUDE)
  704.                    {
  705.                     (void) strncpy(INCLUDE[NINC], &(temp[J]), K - J);
  706.                     INCLUDE[NINC][K - J] = '\0';
  707.                     if (stat(INCLUDE[NINC++], &buf1) != 0)
  708.                        {
  709.                         error(0,
  710.                           "\tUnable to access include directory %s from Dinc\n",
  711.                                                          INCLUDE[NINC-1]);
  712.                        }
  713.  
  714.                    }
  715.                 else
  716.                    {
  717.                     error(0,
  718.             "\tMaximum number of include directories (%d) exceeded in Dinc.\n",
  719.                                                       MAXINCLUDE-1);
  720.                    }
  721.                 J = K;
  722.                }
  723.            }
  724.         while (temp[J] != '\0');
  725.        }
  726.  
  727.     if ((temp = getenv("sDinc")) != NULL)
  728.        {
  729.         J = 0;
  730.         do
  731.            {
  732.             for (; temp[J] == ' ' || temp[J] == '\t' ||
  733.                                                     temp[J] == '\n'; J++);
  734.             for (K = J; temp[K] != ' ' && temp[K] != '\t' &&
  735.                                 temp[K] != '\n' && temp[K] != '\0'; K++);
  736.             if (temp[J] != '\0')
  737.                {
  738.                 if (NINC < MAXINCLUDE)
  739.                    {
  740.                     (void) strncpy(INCLUDE[NINC], &(temp[J]), K - J);
  741.                     INCLUDE[NINC][K - J] = '\0';
  742.                     if (stat(INCLUDE[NINC++], &buf1) != 0)
  743.                        {
  744.                         error(0,
  745.                         "\tUnable to access include directory %s from sDinc\n",
  746.                                                          INCLUDE[NINC-1]);
  747.                        }
  748.  
  749.                    }
  750.                 else
  751.                    {
  752.                     error(0,
  753.             "\tMaximum number of include directories (%d) exceeded in sDinc.\n",
  754.                                                       MAXINCLUDE-1);
  755.                    }
  756.                 J = K;
  757.                }
  758.            }
  759.         while (temp[J] != '\0');
  760.        }
  761.  
  762.         /* If there was no quiet option, we print out the initial message. */
  763.  
  764.     if (! QUIET)
  765.        {
  766.         (void) fprintf(stderr, "\n\n                              DINO %s\n",
  767.                                 version_id);
  768.         (void) fprintf(stderr,
  769.                 "             [DIstributed Numerically Oriented language]\n");
  770.         (void) fprintf(stderr,
  771.         "       (Copyright, 1990, Regents of the University of Colorado)\n\n");
  772.         header = TRUE;
  773.        }
  774.  
  775.     if (macherr)
  776.        {
  777.         error(2, "\tWARNING, no parallel machines defined on this system.\n\t\tOnly the first phase of the compiler will be run\n\t\tfor a basic 16 node iPSC2.\n\n");
  778.        }
  779.  
  780.         /* We make sure that the compiler model is set correctly. */
  781.  
  782.     if (! MODEL)
  783.        {
  784.         if (machines[default_mach].type == 5 ||
  785.                                         machines[default_mach].type == 6)
  786.             TYPE = 's';
  787.         else
  788.            {
  789.             if (machines[default_mach].type == 4)
  790.                 TYPE = 'g';
  791.             else
  792.                 TYPE = 'c';
  793.            }
  794.         if (machines[default_mach].type == 1 ||
  795.                                         machines[default_mach].type == 5)
  796.             SERIES = '1';
  797.         else
  798.             SERIES = '2';
  799.        }
  800.  
  801.         /* We update the cube dimension and check it for correctness: */
  802.  
  803.     if (! macherr)
  804.        {
  805.         if (CUBEDIM == 0)
  806.             CUBEDIM = machines[default_mach].dim;
  807.         else
  808.             if (CUBEDIM < 1 || CUBEDIM > machines[default_mach].maxdim)
  809.                 error(0, "\tUser supplied dimension for %s (-C%d) too large.\n",
  810.                                             machines[default_mach].name, CUBEDIM);
  811.        }
  812.  
  813.         /* We make sure a source file was supplied. */
  814.  
  815.     if (SOURCE[0] == '\0')
  816.         error(1, "\tName of DINO source file was not provided.\n");
  817.  
  818.         /* We extract the root of the source file. */
  819.  
  820.     temp = strrchr(SOURCE, '/');
  821.     if (temp == NULL)
  822.         temp = SOURCE;
  823.     else
  824.         temp++;
  825.     temp2 = strrchr(temp, '.');
  826.     if (temp2 == NULL)
  827.         test = strlen(temp);
  828.     else
  829.         test = temp2 - temp;
  830.     (void) strncpy(ROOT, temp, test);
  831.     ROOT[test] = '\0';
  832.  
  833.         /* We check the user's environment to see if there is a root
  834.            directory for the destination machine to which we should
  835.            append any command line directory (if the command line
  836.            directory starts with a "/" or a "~", then that overrides
  837.            the environment directory).  In addition, if the second
  838.            phase is being done on the same machine as the first phase,
  839.            the environment directory and commend line directories are
  840.            interperted relative to the user's home directory unless
  841.            that is explicitly overridden.                                */
  842.  
  843.     if (DIRECTORY[0] != '\0')
  844.        {
  845.         machines[default_mach].lcl_here = FALSE;
  846.         if (DIRECTORY[0] != '/' && DIRECTORY[0] != '.' && DIRECTORY[0] != '~')
  847.            {
  848.             if (machines[default_mach].directory[0] == '\0')
  849.                 (void) strcpy(machines[default_mach].directory, DIRECTORY);
  850.             else
  851.                {
  852.                 (void) strcat(machines[default_mach].directory, "/");
  853.                 (void) strcat(machines[default_mach].directory, DIRECTORY);
  854.                }
  855.             if (machines[default_mach].rdirectory[0] == '\0')
  856.                 (void) strcpy(machines[default_mach].rdirectory, DIRECTORY);
  857.             else
  858.                {
  859.                 (void) strcat(machines[default_mach].rdirectory, "/");
  860.                 (void) strcat(machines[default_mach].rdirectory, DIRECTORY);
  861.                }
  862.            }
  863.         else
  864.            {
  865.             switch (DIRECTORY[0])
  866.                {
  867.                 case '.':
  868.                     if (machines[I].rcp)
  869.                         error(0,
  870.         "\tInvalid directory (%s) for remote machine %s specified with \"-d\"\n",
  871.                                         DIRECTORY, machines[default_mach].name);
  872.                     (void) strcpy(machines[default_mach].directory, getenv("PWD"));
  873.                     if (DIRECTORY[1] != '\0')
  874.                        {
  875.                         if (DIRECTORY[1] != '/')
  876.                             error(0,
  877.         "\tInvalid directory (%s) for remote machine %s specified with \"-d\"\n",
  878.                                         DIRECTORY, machines[default_mach].name);
  879.                         (void) strcat(machines[default_mach].directory, &(DIRECTORY[1]));
  880.                        }
  881.                     else
  882.                         machines[default_mach].lcl_here = TRUE;
  883.                     if (machines[default_mach].rsh)
  884.                        {
  885.                         home = getenv("HOME");
  886.                         for (J = 0; home[J] != '\0' &&
  887.                                     home[J] == machines[default_mach].directory[J]; J++);
  888.                         K = 0;
  889.                         if (machines[default_mach].directory[J] != '\0')
  890.                             for (J++; machines[default_mach].directory[J] != '\0';
  891.                                                                             J++, K++)
  892.                                 machines[default_mach].rdirectory[K] =
  893.                                                     machines[default_mach].directory[J];
  894.                         machines[default_mach].rdirectory[K] = '\0';
  895.                        }
  896.  
  897.                     break;
  898.                 case '~':
  899.                     if (machines[default_mach].rcp)
  900.                        {
  901.                         if (DIRECTORY[1] == '\0')
  902.                             machines[default_mach].directory[0] = '\0';
  903.                         else
  904.                             if (DIRECTORY[1] == '/')
  905.                                 for (J = 0; DIRECTORY[J] != '\0'; J++)
  906.                                     machines[default_mach].directory[J] = DIRECTORY[J+2];
  907.                              strcpy(machines[default_mach].rdirectory,
  908.                                                     machines[default_mach].directory);
  909.                        }
  910.                     else
  911.                        {
  912.                         if (DIRECTORY[1] == '\0')
  913.                             machines[default_mach].rdirectory[0] = '\0';
  914.                         else
  915.                             if (DIRECTORY[1] == '/')
  916.                                 (void) strcpy(machines[default_mach].rdirectory,
  917.                                                     &(DIRECTORY[2]));
  918.  
  919.                         if (DIRECTORY[1] == '\0' || DIRECTORY[1] == '/')
  920.                            {
  921.                             (void) strcpy(machines[default_mach].directory,
  922.                                                                     getenv("HOME"));
  923.                             if (DIRECTORY[1] == '/')
  924.                                 (void) strcat(machines[default_mach].directory,
  925.                                                                     &(DIRECTORY[1]));
  926.                            }
  927.                         else
  928.                            {
  929.                             for (J = 1; DIRECTORY[J] != '/' &&
  930.                                                         DIRECTORY[J] != '\0'; J++);
  931.                             (void) strncpy(username, &(DIRECTORY[1]), J - 1);
  932.                             username[J-1] = '\0';
  933.                             if ((pwbuf = getpwnam(username)) == NULL)
  934.                                 error(0,
  935.        "\tInvalid directory (%s) for %s specified with \"-d\", no login for %s\n",
  936.                                 DIRECTORY, machines[default_mach].name, username);
  937.                             (void) strcpy(machines[default_mach].directory,
  938.                                                                     pwbuf->pw_dir);
  939.                             if (tempdir[J] != '\0')
  940.                                 (void) strcat(machines[default_mach].directory,
  941.                                                                 &(DIRECTORY[J]));
  942.                            }
  943.                        }
  944.                     break;
  945.                }
  946.            }
  947.        }
  948.     if (DIRECTORY[0] != '\0' && ! machines[default_mach].rcp)
  949.        {
  950.         mask = S_IRWXU | S_IRWXG | S_IRWXO;
  951.         temp2 = DIRECTORY;
  952.         do
  953.            {
  954.             temp2++;
  955.             for (; *temp2 != '/' && *temp2 != '\0'; temp2++);
  956.             (void) strncpy(tempdir, DIRECTORY, temp2 - DIRECTORY);
  957.             tempdir[temp2 - DIRECTORY] = '\0';
  958.             if (stat(tempdir, &buf1) != 0)
  959.                 if(mkdir(tempdir, mask) != 0)
  960.                    {
  961.                     temp = getenv("HOST");
  962.                     error(0,
  963.                         "\tUnable to create directory %s requested on %s\n",
  964.                                                                 tempdir, temp);
  965.                    }
  966.            }
  967.         while (*temp2 != '\0');
  968.        }
  969.  
  970.     if (machines[default_mach].run == 'S')
  971.         special = TRUE;
  972.  
  973.     switch (PARTIAL)
  974.        {
  975.         case 0:
  976.             machines[default_mach].run = 'F';
  977.             break;
  978.         case 1:
  979.             machines[default_mach].run = 'P';
  980.             break;
  981.         case 2:
  982.             machines[default_mach].run = 'T';
  983.             break;
  984.         case 3:
  985.             if (machines[default_mach].run == 'F')
  986.                 PARTIAL = 0;
  987.             else
  988.                 PARTIAL = 2;
  989.        }
  990.  
  991.     if (USER[0] == '\0')
  992.        {
  993.         (void) strcpy(USER, machines[default_mach].user);
  994.         if (machines[default_mach].user[0] == '~')
  995.            {
  996.             if (machines[default_mach].user[1] != '\0')
  997.                 error(0, "\tInvalid user for %s in %s.\n",
  998.                                        machines[default_mach].name, varname);
  999.            }
  1000.         else
  1001.            {
  1002.             if (machines[default_mach].user[0] == '.')
  1003.                 error(0, "\tInvalid user (%s) for %s in %s\n",
  1004.                            machines[default_mach].user,
  1005.                     machines[default_mach].name, varname);
  1006.             if (! machines[default_mach].rsh)
  1007.                 error(0,
  1008.           "\tInvalid user (%s) for %s in %s\n",
  1009.                             machines[default_mach].user,
  1010.                      machines[default_mach].name, varname);
  1011.            }
  1012.        }
  1013.     else
  1014.         if (! machines[default_mach].rsh && USER[0] != '~' && USER[1] != '\0')
  1015.             error(0,
  1016.                  "\tInvalid user (%s) for %s specified with \"-u\" option.\n",
  1017.                                        USER, machines[default_mach].name);
  1018.  
  1019.          /* Now, we generate the output. */
  1020.  
  1021.         /* First, we tell the shell that the command line was correct. */
  1022.  
  1023.     (void) printf("ok\n");
  1024.  
  1025.         /*  Then we tell it what suffix model we are using. */
  1026.  
  1027.     if (SUFFIX_MODEL && ! macherr)
  1028.         (void) printf("new\n");
  1029.     else
  1030.         (void) printf("old\n");
  1031.  
  1032.         /* Then, we generate the actual suffix. */
  1033.  
  1034.     if (SUFFIX[0] == '\0')
  1035.        {
  1036.         if (SUFFIX_MODEL)
  1037.             (void) strcpy(SUFFIX, machines[default_mach].suffix);
  1038.         else
  1039.             switch (machines[default_mach].type)
  1040.                {
  1041.                 case 1:
  1042.                     (void) strcpy(SUFFIX, "D1");
  1043.                     break;
  1044.                 case 2:
  1045.                     (void) strcpy(SUFFIX, "D2");
  1046.                     break;
  1047.                 case 3:
  1048.                     (void) strcpy(SUFFIX, "D8");
  1049.                     break;
  1050.                  case 4:
  1051.                     (void) strcpy(SUFFIX, "G");
  1052.                     break;
  1053.                 case 5:
  1054.                     (void) strcpy(SUFFIX, "S1");
  1055.                     break;
  1056.                 case 6:
  1057.                     (void) strcpy(SUFFIX, "S2");
  1058.                     break;
  1059.               }
  1060.        }
  1061.     (void) printf("%s\n", SUFFIX);
  1062.  
  1063.         /* Then we give it the name of the source file. */
  1064.  
  1065.     (void) printf("%s\n", SOURCE);
  1066.  
  1067.         /* Then we generate a string with all the include directories in it. */
  1068.  
  1069.     for (I = 0; I < NINC; I++)
  1070.        {
  1071.         (void) printf("-I%s", INCLUDE[I]);
  1072.         if (I < NINC - 1)
  1073.             (void) printf(" ");
  1074.        }
  1075.     if (NINC == 0)
  1076.         (void) printf(" ");
  1077.     (void) printf("\n");
  1078.  
  1079.         /* Next, we generate a string with all the compiler options in it. */
  1080.  
  1081.     used = FALSE;
  1082.     if (BUFSIZE > 0)
  1083.        {
  1084.         if (used)
  1085.             (void) printf(" ");
  1086.         (void) printf("-B%d", BUFSIZE);
  1087.         used = TRUE;
  1088.        }
  1089.     if (FIRSTTYPE > 0)
  1090.        {
  1091.         if (used)
  1092.             (void) printf(" ");
  1093.         (void) printf("-S%d", FIRSTTYPE);
  1094.         used = TRUE;
  1095.        }
  1096.     if (LASTTYPE > 0)
  1097.        {
  1098.         if (used)
  1099.             (void) printf(" ");
  1100.         (void) printf("-L%d", LASTTYPE);
  1101.         used = TRUE;
  1102.        }
  1103.     if (used)
  1104.         (void) printf(" ");
  1105.     (void) printf("-M%c%c ", TYPE, SERIES);
  1106.     (void) printf("-C%d\n", CUBEDIM);
  1107.  
  1108.         /* Next, we generate a string with all the formatter options in it. */
  1109.  
  1110.     used = FALSE;
  1111.     if (ALADIN)
  1112.        {
  1113.         (void) printf("-a");
  1114.         used = TRUE;
  1115.        }
  1116.     if (WARNINGS)
  1117.        {
  1118.         if (used)
  1119.             (void) printf(" ");
  1120.         (void) printf("-w");
  1121.         used = TRUE;
  1122.        }
  1123.     if (COMMENTS)
  1124.        {
  1125.         if (used)
  1126.             (void) printf(" ");
  1127.         (void) printf("-c");
  1128.         used = TRUE;
  1129.        }
  1130.     if (NOTES)
  1131.        {
  1132.         if (used)
  1133.             (void) printf(" ");
  1134.         (void) printf("-n");
  1135.         used = TRUE;
  1136.        }
  1137.     if (NUMBERS)
  1138.        {
  1139.         if (used)
  1140.             (void) printf(" ");
  1141.         (void) printf("-l");
  1142.         used = TRUE;
  1143.        }
  1144.     if (ORDER)
  1145.        {
  1146.         if (used)
  1147.             (void) printf(" ");
  1148.         (void) printf("-e");
  1149.         used = TRUE;
  1150.        }
  1151.     if (! used)
  1152.         (void) printf(" ");
  1153.     (void) printf("\n");
  1154.  
  1155.         /* Next, we generate a string with all the splitter options in it. */
  1156.  
  1157.     if (! SUFFIX_MODEL)
  1158.         (void) printf("-o ");
  1159.     (void) printf("-s%s\n", SUFFIX);
  1160.  
  1161.         /* Next, we generate the name of the target machine. */
  1162.  
  1163.     if (macherr)
  1164.         (void) printf(" \n");
  1165.     else
  1166.         (void) printf("%s\n", machines[default_mach].name);
  1167.  
  1168.         /* Then, we generate the root name of the source file. */
  1169.  
  1170.     (void) printf("%s\n", ROOT);
  1171.  
  1172.         /* Next, we generate the copy command that should be used
  1173.                     (note there are two parts). */
  1174.  
  1175.     if (machines[default_mach].run == 'T' || machines[default_mach].run == 'P')
  1176.        {
  1177.         if (machines[default_mach].rcp)
  1178.            {
  1179.             (void) strcpy(OUTLINE, "rcp");
  1180.             if (machines[default_mach].date)
  1181.                 (void) strcat(OUTLINE, " -p");
  1182.            }
  1183.         else
  1184.            {
  1185.             if (machines[default_mach].lcl_here)
  1186.                 (void) strcpy(OUTLINE, " ");
  1187.             else
  1188.                 (void) strcpy(OUTLINE, "cp -p");
  1189.            }
  1190.        }
  1191.     else
  1192.         (void) strcpy(OUTLINE, " ");
  1193.     (void) printf("%s\n", OUTLINE);
  1194.  
  1195.     if (machines[default_mach].run == 'T' || machines[default_mach].run == 'P')
  1196.        {
  1197.         if (machines[default_mach].rcp)
  1198.            {
  1199.             if (USER[0] != '~' || USER[1] != '\0')
  1200.                {
  1201.                 (void) strcpy(OUTLINE, USER);
  1202.                 (void) strcat(OUTLINE, "@");
  1203.                }
  1204.             else
  1205.                 OUTLINE[0] = '\0';
  1206.             (void) strcat(OUTLINE, machines[default_mach].address);
  1207.             (void) strcat(OUTLINE, ":");
  1208.             (void) strcat(OUTLINE, machines[default_mach].rdirectory);
  1209.            }
  1210.         else
  1211.            {
  1212.             if (machines[default_mach].lcl_here)
  1213.                {
  1214.                 (void) strcpy(OUTLINE, " ");
  1215.                }
  1216.             else
  1217.                {
  1218.                 (void) strcpy(OUTLINE, machines[default_mach].directory);
  1219.                }
  1220.            }
  1221.        }
  1222.     else
  1223.         (void) strcpy(OUTLINE, " ");
  1224.     (void) printf("%s\n", OUTLINE);
  1225.  
  1226.  
  1227.         /* Next, we generate the execute command that should be used. */
  1228.  
  1229.     if (machines[default_mach].run == 'T')
  1230.        {
  1231.         if (machines[default_mach].rsh)
  1232.            {
  1233.             (void) strcpy(OUTLINE, "rsh ");
  1234.             (void) strcat(OUTLINE, machines[default_mach].address);
  1235.             (void) strcat(OUTLINE, " ");
  1236.             if (USER[0] != '~' || USER[1] != '\0')
  1237.                {
  1238.                 (void) strcat(OUTLINE, "-l ");
  1239.                 (void) strcat(OUTLINE, USER);
  1240.                 (void) strcat(OUTLINE, " ");
  1241.                }
  1242.             if (machines[default_mach].rdirectory[0] != '\0')
  1243.                {
  1244.                 (void) strcat(OUTLINE, "cd ");
  1245.                 (void) strcat(OUTLINE, machines[default_mach].rdirectory);
  1246.                 (void) strcat(OUTLINE, "; ");
  1247.                }
  1248.             (void) strcat(OUTLINE, "dino2 ");
  1249.             if (QUIET)
  1250.                 (void) strcat(OUTLINE, "T ");
  1251.             else
  1252.                 (void) strcat(OUTLINE, "F ");
  1253.             (void) strcat(OUTLINE, machines[default_mach].name);
  1254.             if (SUFFIX_MODEL)
  1255.                 (void) strcat(OUTLINE, " new ");
  1256.             else
  1257.                 (void) strcat(OUTLINE, " old ");
  1258.             (void) strcat(OUTLINE, SUFFIX);
  1259.            }
  1260.         else
  1261.            {
  1262.             (void) strcpy(OUTLINE, "dino2 ");
  1263.             if (QUIET)
  1264.                 (void) strcat(OUTLINE, "T ");
  1265.             else
  1266.                 (void) strcat(OUTLINE, "F ");
  1267.             (void) strcat(OUTLINE, machines[default_mach].name);
  1268.             if (SUFFIX_MODEL)
  1269.                 (void) strcat(OUTLINE, " new ");
  1270.             else
  1271.                 (void) strcat(OUTLINE, " old ");
  1272.             (void) strcat(OUTLINE, SUFFIX);
  1273.            }
  1274.        }
  1275.     else
  1276.         (void) strcpy(OUTLINE, " ");
  1277.     (void) printf("%s\n", OUTLINE);
  1278.  
  1279.         /* Then we generate a change directory command if we
  1280.                                   need it for the local machine. */
  1281.  
  1282.     if (machines[default_mach].run == 'T' &&
  1283.            ! machines[default_mach].rsh && ! machines[default_mach].lcl_here)
  1284.        {
  1285.         (void) strcpy(OUTLINE, "cd ");
  1286.         (void) strcat(OUTLINE, machines[default_mach].directory);
  1287.        }
  1288.     else
  1289.         (void) strcpy(OUTLINE, " ");
  1290.     (void) printf("%s\n", OUTLINE);
  1291.  
  1292.         /* Next, we generate the create directory
  1293.                                     command that should be used. */
  1294.  
  1295.     if ((machines[default_mach].run == 'T' ||
  1296.                     machines[default_mach].run == 'P') &&
  1297.                                     machines[default_mach].rdirectory[0] != '\0')
  1298.        {
  1299.         if (machines[default_mach].rcp)
  1300.            {
  1301.             (void) strcpy(OUTLINE, "rsh ");
  1302.             (void) strcat(OUTLINE, machines[default_mach].address);
  1303.             if (USER[0] != '~' || USER[1] != '\0')
  1304.                {
  1305.                 (void) strcat(OUTLINE, " -l ");
  1306.                 (void) strcat(OUTLINE, USER);
  1307.                }
  1308.             (void) strcat(OUTLINE, " dinocrdr ");
  1309.             (void) strcat(OUTLINE, machines[default_mach].rdirectory);
  1310.            }
  1311.         else
  1312.            {
  1313.             (void) strcpy(OUTLINE, " ");
  1314.            }
  1315.        }
  1316.     else
  1317.         (void) strcpy(OUTLINE, " ");
  1318.     (void) printf("%s\n", OUTLINE);
  1319.  
  1320.         /* Next, we generate a string with the local directory in it. */
  1321.  
  1322.     if (machines[default_mach].directory[0] != '\0')
  1323.         (void) printf("%s\n", machines[default_mach].directory);
  1324.     else
  1325.         (void) printf(" \n");
  1326.  
  1327.         /* Then, we generate a string with the user name in it. */
  1328.  
  1329.     if (USER[0] != '\0')
  1330.         (void) printf("%s\n", USER);
  1331.     else
  1332.         (void) printf(" \n");
  1333.  
  1334.         /* Next, we generate a string with the machine address in it. */
  1335.  
  1336.     if (macherr)
  1337.         (void) printf(" \n");
  1338.     else
  1339.         (void) printf("%s\n", machines[default_mach].address);
  1340.  
  1341.         /* Then, we generate the quiet flag. */
  1342.  
  1343.     (void) printf("%s\n", QUIET?"T":"F");
  1344.  
  1345.         /* Next, we generate the partial flag. */
  1346.  
  1347.     (void) printf("%d\n", PARTIAL);
  1348.  
  1349.         /* Then, we generate the rcp flag. */
  1350.  
  1351.     if (machines[default_mach].lcl_here)
  1352.         (void) printf("%s\n", "N");
  1353.     else
  1354.         (void) printf("%s\n", machines[default_mach].rcp?"R":"L");
  1355.  
  1356.         /* Next, we generate the rsh flag. */
  1357.  
  1358.     (void) printf("%s\n", machines[default_mach].rsh?"T":"F");
  1359.  
  1360.         /* Finally, we generate the special flag. */
  1361.  
  1362.     (void) printf("%s\n", special?"T":"F");
  1363.  
  1364.     return(0);
  1365.    }
  1366.  
  1367.  
  1368. /*VARARGS*/
  1369. static void
  1370. error(va_alist)
  1371. va_dcl
  1372. {
  1373.     va_list ap;
  1374.     char *fmt;
  1375.     int type;
  1376.     static BOOL first = TRUE;
  1377.  
  1378.     if (! header && ! QUIET)
  1379.        {
  1380.         (void) fprintf(stderr, "\n\n                              DINO %s\n",
  1381.                                 version_id);
  1382.         (void) fprintf(stderr,
  1383.                 "             [DIstributed Numerically Oriented language]\n");
  1384.         (void) fprintf(stderr,
  1385.         "       (Copyright, 1990, Regents of the University of Colorado)\n\n");
  1386.         header = TRUE;
  1387.        }
  1388.  
  1389.     if (first)
  1390.        {
  1391.         (void) fprintf(stderr, "\n");
  1392.         first = FALSE;
  1393.        }
  1394.  
  1395.     va_start(ap);
  1396.     type = va_arg(ap, int);
  1397.     fmt = va_arg(ap, char *);
  1398.     (void) _doprnt(fmt, ap, stderr);
  1399.     va_end(ap);
  1400.  
  1401.     (void) fprintf(stderr, "\n");
  1402.  
  1403.     if (type == 1)
  1404.         sh_message();
  1405.  
  1406.     if (type < 2)
  1407.        {
  1408.         (void) printf("doa");
  1409.         exit(1);
  1410.        }
  1411. }
  1412.  
  1413. static void sh_message()
  1414.    {
  1415.     if (! header && ! QUIET)
  1416.        {
  1417.         (void) fprintf(stderr, "\n\n                              DINO %s\n",
  1418.                                 version_id);
  1419.         (void) fprintf(stderr,
  1420.                 "             [DIstributed Numerically Oriented language]\n");
  1421.         (void) fprintf(stderr,
  1422.         "       (Copyright, 1990, Regents of the University of Colorado)\n\n");
  1423.        }
  1424.     (void) fprintf(stderr, "Usage: dino [-<machine name>] [-w] [-c] [-n] [-l] [-e] [-o] [-p] [-D]\n");
  1425.     (void) fprintf(stderr, "            [-P] [-Q] [-h[elp]] [-s <suffix>] [-C <num>] [-d <directory>]\n");
  1426.     (void) fprintf(stderr, "            [-u <user>] [-I <directory>] <file>\n\n");
  1427.    }
  1428.  
  1429.  
  1430. static void message()
  1431.    {
  1432.     sh_message();
  1433.     (void) fprintf(stderr, "Where:\n");
  1434.     (void) fprintf(stderr, "   <machine name> - generates code for this parallel machine\n");
  1435.     (void) fprintf(stderr, "                w - does not print compiler warnings\n");
  1436.     (void) fprintf(stderr, "                c - prints compiler comments\n");
  1437.     (void) fprintf(stderr, "                n - prints compiler notes\n");
  1438.     (void) fprintf(stderr, "                f - prints entire source listing\n");
  1439.     (void) fprintf(stderr, "                l - numbers the lines in the listing\n");
  1440.     (void) fprintf(stderr, "                e - print errors in the order they come out of compiler\n");
  1441.     (void) fprintf(stderr, "                o - uses the old style model for building suffixes\n");
  1442.     (void) fprintf(stderr, "                p - stops after the C files are copied to the parallel machine\n");
  1443.     (void) fprintf(stderr, "                D - prints out all the current system defaults\n");
  1444.     (void) fprintf(stderr, "                P - stops after the C files are generated\n");
  1445.     (void) fprintf(stderr, "                Q - only prints out error messages\n");
  1446.     (void) fprintf(stderr, "           h[elp] - prints this message\n");
  1447.     (void) fprintf(stderr, "       s <suffix> - appends <suffix> to the names of the generated C files\n");
  1448.     (void) fprintf(stderr, "          C <num> - set cube dimension to <num>\n");
  1449.     (void) fprintf(stderr, "    d <directory> - uses <directory> to do the work on the parallel machine\n");
  1450.     (void) fprintf(stderr, "         u <user> - set the user on the parallel machine to <user>\n");
  1451.     (void) fprintf(stderr, "    I <directory> - look for include files in <directory>\n                    (more than one \"-I <directory>\" can be used)\n");
  1452.     (void) fprintf(stderr, "           <file> - name of the DINO file to be compiled\n\n");
  1453.     (void) fprintf(stderr, "     Any of the on/off options can be turned off by preceeding it\n          with a \"^\", for example, \"-^w\"\n\n");
  1454.  
  1455.    }
  1456.  
  1457. static void dmessage()
  1458.    {
  1459.     message();
  1460.     (void) fprintf(stderr, "The following additional options are supported for diagnostic purposes --\n");
  1461.     (void) fprintf(stderr, "      [-a] [-H[ELP]] [-B <num>] [-S <num>] [-L <num>] [-M<let><num>]\n\n");
  1462.     (void) fprintf(stderr, "Where:\n");
  1463.     (void) fprintf(stderr, "                a - prints aladin line numbers for errors\n");
  1464.     (void) fprintf(stderr, "           H[ELP] - prints this message\n");
  1465.     (void) fprintf(stderr, "          B <num> - sets buffer size to <num>\n");
  1466.     (void) fprintf(stderr, "          S <num> - set first message type to <num>\n");
  1467.     (void) fprintf(stderr, "          L <num> - set last message type to <num>\n");
  1468.     (void) fprintf(stderr, "      M<let><num> - set machine model to M<let><num> where:\n");
  1469.     (void) fprintf(stderr, "                        <let> = s (simulator), c (cube), or g (grail) and\n");
  1470.     (void) fprintf(stderr, "                        <num> = 1 (ipsc1) or 2 (ipsc2 or i860))\n\n");
  1471.    }
  1472.  
  1473. static void cmdlnparse(argc, argv, output)
  1474.     int argc;
  1475.     char *argv[];
  1476.     char *output;
  1477.    {
  1478.     int I, J, K;
  1479.     int count = 0;
  1480.     BOOL bingo;
  1481.     char option[LINESIZE];
  1482.     char *temp, *temp2;
  1483.     char varname[MAXMACHNAME + 6];
  1484.     char tempdir[MAXPATHLEN];
  1485.     char holder[MAXPATHLEN];
  1486.     char name[MAXMACHNAME];
  1487.     char user[NAMESIZE];
  1488.     char username[25];
  1489.     struct passwd *pwbuf;
  1490.     struct stat buf1;
  1491.     BOOL found = FALSE;
  1492.     BOOL current;
  1493.     BOOL explicit = FALSE;
  1494.  
  1495.     if (argc < 2)
  1496.        {
  1497.         message();
  1498.         (void) printf("doa");
  1499.         exit(1);
  1500.        }
  1501.  
  1502.     for (I = 1; I < argc; I++)
  1503.        {
  1504.         if (argv[I][0] == '-')
  1505.            {
  1506.             bingo = FALSE;
  1507.             for (J = 0; J < nummach; J++)
  1508.                {
  1509.                 if (strcmp(&(argv[I][1]), machines[J].name) == 0)
  1510.                    {
  1511.                     if (explicit)
  1512.                         error(1,
  1513.             "\tMultiple machine names (%s, %s) specified on command line.\n",
  1514.                                 machines[default_mach].name, machines[J].name);
  1515.                     default_mach = J;
  1516.                     bingo = TRUE;
  1517.                     explicit = TRUE;
  1518.                     break;
  1519.                    }
  1520.                }
  1521.             if (bingo)
  1522.                 continue;
  1523.  
  1524.             if (argv[I][1] == '^')
  1525.                {
  1526.                 output[count++] = '^';
  1527.                 for (J = 0; argv[I][J] != '\0'; J++)
  1528.                     option[J] = argv[I][J+1];
  1529.                }
  1530.             else
  1531.                 (void) strcpy(option, argv[I]);
  1532.  
  1533.             switch (option[1])
  1534.                {
  1535.                 case 'a':
  1536.                     if (option[2] == '\0')
  1537.                         output[count++] = 'a';
  1538.                     else
  1539.                         error(1, "\tNon-existent DINO option: %s\n", argv[I]);
  1540.                     break;
  1541.                 case 'c':
  1542.                     if (option[2] == '\0')
  1543.                         output[count++] = 'c';
  1544.                     else
  1545.                         error(1, "\tNon-existent DINO option: %s\n", argv[I]);
  1546.                     break;
  1547.                 case 'd':
  1548.                     if (option[2] == '\0')
  1549.                        {
  1550.                         if (I + 1 < argc && argv[I+1][0] != '-')
  1551.                            {
  1552.                             (void) strcpy(DIRECTORY, &(argv[I+1][0]));
  1553.                             I++;
  1554.                            }
  1555.                         else
  1556.                             error(0, "\tMissing argument to DINO option: %s\n",
  1557.                                                                         argv[I]);
  1558.                        }
  1559.                     else
  1560.                         (void) strcpy(DIRECTORY, &(option[2]));
  1561.                     break;
  1562.                 case 'e':
  1563.                     if (option[2] == '\0')
  1564.                         output[count++] = 'e';
  1565.                     else
  1566.                         error(1, "\tNon-existent DINO option: %s\n", argv[I]);
  1567.                     break;
  1568.                  case 'h':
  1569.                     if (option[2] == '\0' || (strcmp(&(option[1]), "help") == 0))
  1570.                        {
  1571.                         message();
  1572.                         (void) printf("quit");
  1573.                         exit(0);
  1574.                        }
  1575.                     else
  1576.                         error(1, "\tNon-existent DINO option: %s\n", argv[I]);
  1577.                     break;
  1578.                case 'l':
  1579.                     if (option[2] == '\0')
  1580.                         output[count++] = 'l';
  1581.                     else
  1582.                         error(1, "\tNon-existent DINO option: %s\n", argv[I]);
  1583.                     break;
  1584.                 case 'n':
  1585.                     if (option[2] == '\0')
  1586.                         output[count++] = 'n';
  1587.                     else
  1588.                         error(1, "\tNon-existent DINO option: %s\n", argv[I]);
  1589.                     break;
  1590.                 case 'o':
  1591.                     if (option[2] == '\0')
  1592.                         output[count++] = 'o';
  1593.                     else
  1594.                         error(1, "\tNon-existent DINO option: %s\n", argv[I]);
  1595.                     break;
  1596.                 case 'p':
  1597.                     if (option[2] == '\0')
  1598.                         output[count++] = 'p';
  1599.                     else
  1600.                         error(1, "\tNon-existent DINO option: %s\n", argv[I]);
  1601.                     break;
  1602.                 case 's':
  1603.                     if (option[2] == '\0')
  1604.                        {
  1605.                         if (I + 1 < argc && argv[I+1][0] != '-')
  1606.                            {
  1607.                             (void) strcpy(SUFFIX, &(argv[I+1][0]));
  1608.                             I++;
  1609.                            }
  1610.                         else
  1611.                             error(0, "\tMissing argument to DINO option: %s\n",
  1612.                                                                         argv[I]);
  1613.                        }
  1614.                     else
  1615.                         (void) strcpy(SUFFIX, &(option[2]));
  1616.                     break;
  1617.                 case 'u':
  1618.                     if (option[2] == '\0')
  1619.                        {
  1620.                         if (I + 1 < argc && argv[I+1][0] != '-')
  1621.                            {
  1622.                             (void) strcpy(USER, &(argv[I+1][0]));
  1623.                             I++;
  1624.                            }
  1625.                         else
  1626.                             error(0, "\tMissing argument to DINO option: %s\n",
  1627.                                                                         argv[I]);
  1628.                        }
  1629.                     else
  1630.                         (void) strcpy(USER, &(option[2]));
  1631.                     break;
  1632.                 case 'w':
  1633.                     if (option[2] == '\0')
  1634.                         output[count++] = 'w';
  1635.                     else
  1636.                         error(1, "\tNon-existent DINO option: %s\n", argv[I]);
  1637.                     break;
  1638.                 case 'B':
  1639.                     if (option[2] == '\0')
  1640.                        {
  1641.                         if (I + 1 >= argc || argv[I+1][0] == '-' ||
  1642.                                    (BUFSIZE = strtol(argv[I+1], &temp, 0)) == 0 ||
  1643.                                                                 temp[0] != '\0')
  1644.                            {
  1645.                             if (I + 1 >= argc || argv[I+1][0] == '-')
  1646.                                 error(0, "\tMissing argument to DINO option: %s\n",
  1647.                                                                         argv[I]);
  1648.                             else
  1649.                                 error(0,
  1650.                                     "\tInvalid argument to DINO option: %s %s\n",
  1651.                                                               argv[I], argv[I+1]);
  1652.                            }
  1653.                        }
  1654.                     else
  1655.                         if ((BUFSIZE = strtol(&(option[2]), &temp, 0)) == 0 ||
  1656.                                                                 temp[0] != '\0')
  1657.                             error(0, "\tInvalid argument to DINO option: %s\n",
  1658.                                                                         argv[I]);
  1659.                     break;
  1660.                 case 'C':
  1661.                     if (option[2] == '\0')
  1662.                        {
  1663.                         if (I + 1 >= argc || argv[I+1][0] == '-' ||
  1664.                                    (CUBEDIM = strtol(argv[I+1], &temp, 0)) == 0 ||
  1665.                                                                 temp[0] != '\0')
  1666.                            {
  1667.                             if (I + 1 >= argc || argv[I+1][0] == '-')
  1668.                                 error(0, "\tMissing argument to DINO option: %s\n",
  1669.                                                                         argv[I]);
  1670.                             else
  1671.                                 error(0,
  1672.                                     "\tInvalid argument to DINO option: %s %s\n",
  1673.                                                               argv[I], argv[I+1]);
  1674.                            }
  1675.                         I++;
  1676.                        }
  1677.                     else
  1678.                         if ((CUBEDIM = strtol(&(option[2]), &temp, 0)) == 0 ||
  1679.                                                                 temp[0] != '\0')
  1680.                             error(0, "\tInvalid argument to DINO option: %s\n",
  1681.                                                                         argv[I]);
  1682.                     break;
  1683.                 case 'D':
  1684.                     if (option[2] != '\0')
  1685.                        {
  1686.                         error(0, "\tNon-existent DINO option: %s\n", argv[I]);
  1687.                        }
  1688.                     if (I + 1 < argc && argv[I+1][0] != '-')
  1689.                        {
  1690.                         error(0, "\tNon-existent DINO option: %s %s\n",
  1691.                                                           argv[I], argv[I+1]);
  1692.                        }
  1693.                     if (! QUIET)
  1694.                        {
  1695.                (void) fprintf(stderr, "\n\n                              DINO\n");
  1696.                         (void) fprintf(stderr,
  1697.                 "             [DIstributed Numerically Oriented language]\n");
  1698.                         (void) fprintf(stderr,
  1699.         "       (Copyright, 1990, Regents of the University of Colorado)\n\n");
  1700.                        }
  1701.                     else
  1702.                         (void) fprintf(stderr,"\n");
  1703.                     if ((temp = getenv("Dmachs")) == NULL)
  1704.                        {
  1705.                         (void) fprintf(stderr,
  1706.                             "\tNo parallel machines defined on this system.\n\n");
  1707.                         (void) printf("quit\n");
  1708.                         exit(0);
  1709.                        }
  1710.                     if (temp[0] == '\0')
  1711.                        {
  1712.                         (void) fprintf(stderr,
  1713.                             "\tNo parallel machines defined on this system.\n\n");
  1714.                         (void) printf("quit\n");
  1715.                         exit(0);
  1716.                        }
  1717.                     if ((temp2 = getenv("sDmachine")) == NULL)
  1718.                         default_mach = 0;
  1719.                     else
  1720.                        {
  1721.                         for (I = 0; I < nummach; I++)
  1722.                             if (strcmp(temp2, machines[I].name) == 0)
  1723.                                {
  1724.                                 default_mach = I;
  1725.                                 break;
  1726.                                }
  1727.                        }
  1728.                     (void) fprintf(stderr,
  1729.         "    The following machines and defaults are defined by the system:\n");
  1730.                     J = 0;
  1731.                     for (I = 0; I < MAXMACHINES; I++)
  1732.                        {
  1733.                         for (; temp[J] == ' ' || temp[J] == '\t' ||
  1734.                                                         temp[J] == '\n'; J++);
  1735.                         if (temp[J] == '\0')
  1736.                             break;
  1737.                         for (K = 0; temp[J] != ' ' && temp[J] != '\0' &&
  1738.                                     temp[J] != '\t' && temp[J] != '\n'; J++, K++)
  1739.                            name[K] = temp[J];
  1740.                         name[K] = '\0';
  1741.                         (void) fprintf(stderr, "\n        %s -->\n", name);
  1742.                         for (; temp[J] == ' ' || temp[J] == '\t' ||
  1743.                                                             temp[J] == '\n'; J++);
  1744.                         for (K = 0; temp[J] != ' ' && temp[J] != '\0' &&
  1745.                                     temp[J] != '\t' && temp[J] != '\n'; J++, K++)
  1746.                             holder[K] = temp[J];
  1747.                         holder[K] = '\0';
  1748.                         if (holder[0] == '.')
  1749.                             (void) fprintf(stderr,
  1750.                         "            the current machine will be used as the target\n");
  1751.                         else
  1752.                             (void) fprintf(stderr,
  1753.                     "            the address of the target machine is %s\n", holder);
  1754.                         for (; temp[J] == ' ' || temp[J] == '\t' ||
  1755.                                                             temp[J] == '\n'; J++);
  1756.                         for (K = 0; temp[J] != ' ' && temp[J] != '\0' &&
  1757.                                     temp[J] != '\t' && temp[J] != '\n'; J++, K++)
  1758.                            user[K] = temp[J];
  1759.                         user[K] = '\0';
  1760.                         current = FALSE;
  1761.                         if (user[0] == '~')
  1762.                            {
  1763.                             temp2 = getenv("USER");
  1764.                             (void) strcpy(user, temp2);
  1765.                             current = TRUE;
  1766.                            }
  1767.                         (void) fprintf(stderr,
  1768.                                         "            the target user is %s", user);
  1769.                         if (current)
  1770.                             (void) fprintf(stderr, " (the current user)\n");
  1771.                         else
  1772.                             (void) fprintf(stderr, "\n");
  1773.                         for (; temp[J] == ' ' || temp[J] == '\t' ||
  1774.                                                         temp[J] == '\n'; J++);
  1775.                         for (K = 0; temp[J] != ' ' && temp[J] != '\0' &&
  1776.                                     temp[J] != '\t' && temp[J] != '\n'; J++, K++)
  1777.                            holder[K] = temp[J];
  1778.                         holder[K] = '\0';
  1779.                         current = FALSE;
  1780.                         switch (holder[0])
  1781.                            {
  1782.                             case '.':
  1783.                                 (void) strcpy(tempdir, holder);
  1784.                                 (void) strcpy(holder, getenv("PWD"));
  1785.                                 if (tempdir[1] != '\0')
  1786.                                     (void) strcat(holder, &(tempdir[1]));
  1787.                                 current = TRUE;
  1788.                                 break;
  1789.                             case '~':
  1790.                                 if (machines[I].rcp)
  1791.                                    {
  1792.                                     if (holder[1] == '\0')
  1793.                                         holder[0] = '\0';
  1794.                                     else
  1795.                                         if (holder[1] == '/')
  1796.                                             for (J = 0; holder[J] != '\0'; J++)
  1797.                                                 holder[J] = holder[J+2];
  1798.                                    }
  1799.                                 else
  1800.                                    {
  1801.                                     (void) strcpy(tempdir, holder);
  1802.                                     if (tempdir[1] == '\0' || tempdir[1] == '/')
  1803.                                        {
  1804.                                         (void) strcpy(holder, getenv("HOME"));
  1805.                                         if (tempdir[1] == '/')
  1806.                                             (void) strcat(holder, &(tempdir[1]));
  1807.                                        }
  1808.                                     else
  1809.                                        {
  1810.                                         for (J = 1; tempdir[J] != '/' &&
  1811.                                                          tempdir[J] != '\0'; J++);
  1812.                                         (void) strncpy(username,
  1813.                                                             &(tempdir[1]), J - 1);
  1814.                                         username[J-1] = '\0';
  1815.                                         pwbuf = getpwnam(username);
  1816.                                         (void) strcpy(holder, pwbuf->pw_dir);
  1817.                                         if (tempdir[J] != '\0')
  1818.                                             (void) strcat(holder, &(tempdir[J]));
  1819.                                        }
  1820.                                    }
  1821.                                 break;
  1822.                            }
  1823.                         if (strlen(holder) > 0)
  1824.                            {
  1825.                             if (machines[I].rcp)
  1826.                                 (void) fprintf(stderr,
  1827.         "            the destination directory is\n                ~%s/%s\n                on %s\n", user, holder, name);
  1828.                             else
  1829.                                {
  1830.                                 (void) fprintf(stderr,
  1831.             "            the destination directory is\n                %s\n                on this machine\n", holder);
  1832.                                 if (current)
  1833.                                     (void) fprintf(stderr,
  1834.                         "                (directory is relative to current directory)\n");
  1835.                                }
  1836.                            }
  1837.                         else
  1838.                             (void) fprintf(stderr,
  1839.                     "            the destination directory is ~%s on %s\n", user, name);
  1840.                         for (; temp[J] == ' ' || temp[J] == '\t' ||
  1841.                                                             temp[J] == '\n'; J++);
  1842.                         (void) fprintf(stderr, "            the target machine is ");
  1843.                         switch (temp[J++])
  1844.                            {
  1845.                             case 's' :
  1846.                                 (void) fprintf(stderr, "an iPSC1 simulator\n");
  1847.                                 break;
  1848.                             case 'S' :
  1849.                                 (void) fprintf(stderr, "an iPSC2 simulator\n");
  1850.                                 break;
  1851.                             case '1' :
  1852.                                 (void) fprintf(stderr, "an iPSC1\n");
  1853.                                 break;
  1854.                             case '2' :
  1855.                                 (void) fprintf(stderr, "an iPSC2\n");
  1856.                                 break;
  1857.                             case '8' :
  1858.                                 (void) fprintf(stderr,
  1859.                                                 "an i860 version of the iPSC2\n");
  1860.                                 break;
  1861.                             case 'G' :
  1862.                                 (void) fprintf(stderr,
  1863.                                                 "a distributed sun machine\n");
  1864.                                 break;
  1865.                            }
  1866.                         (void) fprintf(stderr,
  1867.                                 "            largest allowable dimension is %d.\n",
  1868.                                 (int) strtol(&(temp[J++]), (char **) NULL, 0));
  1869.                         for (; isdigit(temp[J]); J++);
  1870.                         J += 4;
  1871.                         switch (machines[I].run)
  1872.                            {
  1873.                             case 'T':
  1874.                                 if (machines[I].rcp)
  1875.                                    {
  1876.                                     if (machines[I].rsh)
  1877.                                        {
  1878.                                         if (machines[I].date)
  1879.                                            {
  1880.                                             (void) fprintf(stderr,
  1881.                             "            intermediate files will be copied to %s and\n",
  1882.                                                                         name);
  1883.                                             (void) fprintf(stderr,
  1884.                 "                compiled there for any file that has been changed\n");
  1885.                                            }
  1886.                                         else
  1887.                                            {
  1888.                                             (void) fprintf(stderr,
  1889.                         "            intermediate files will be copied to %s and \n",
  1890.                                                                           name);
  1891.                                             (void) fprintf(stderr,
  1892.                 "                compiled there (DINO is not able to check dates)\n");
  1893.                                            }
  1894.                                        }
  1895.                                     else
  1896.                                        {
  1897.                                         (void) fprintf(stderr,
  1898.                             "            intermediate files will be copied to %s\n",
  1899.                                                                             name);
  1900.                                        }
  1901.                                    }
  1902.                                 else
  1903.                                    {
  1904.                                     if (machines[I].rsh)
  1905.                                        {
  1906.                                         (void) fprintf(stderr,
  1907.         "            intermediate files will be copied to the destination directory\n");
  1908.                                         (void) fprintf(stderr,
  1909.                     "                and compiled there if they have been changed\n");
  1910.                                        }
  1911.                                     else
  1912.                                        {
  1913.                                         (void) fprintf(stderr,
  1914.         "            intermediate files will be copied to the destination directory");
  1915.                                         (void) fprintf(stderr,
  1916.                                                 "                but not compiled\n");
  1917.                                        }
  1918.                                    }
  1919.                                 break;
  1920.                             case 'F':
  1921.                                 (void) fprintf(stderr,
  1922.                     "            only the intermediate files will be generated\n");
  1923.                                 break;
  1924.                             case 'S':
  1925.                                 (void) fprintf(stderr,
  1926.                 "            there is custom code for compilation on this machine\n");
  1927.                                 (void) fprintf(stderr,
  1928.                      "                see the \"dino.special\" shell script to examine it\n");
  1929.                                 break;
  1930.                            }
  1931.                         (void) fprintf(stderr,
  1932.                                 "            the default dimension is %d.\n",
  1933.                                 (int) strtol(&(temp[J++]), (char **) NULL, 0));
  1934.                         for (; isdigit(temp[J]); J++);
  1935.                         (void) sprintf(varname, "sD%sopt", name);
  1936.                         if ((temp2 = getenv(varname)) != NULL)
  1937.                            {
  1938.                             for (K = 0; temp2[K] != '\0'; K++)
  1939.                                {
  1940.                                 if (temp2[K] == '!')
  1941.                                     continue;
  1942.                                 switch (temp2[K])
  1943.                                    {
  1944.                                     case 'a':
  1945.                                         (void) fprintf(stderr,
  1946.                                  "            ALADIN line numbers will be printed\n");
  1947.                                         break;
  1948.                                     case 'c':
  1949.                                         (void) fprintf(stderr,
  1950.                                "            DINO compiler comments will be printed\n");
  1951.                                         break;
  1952.                                     case 'e':
  1953.                                          (void) fprintf(stderr,
  1954.                   "            DINO will print errors in the order it detects them\n");
  1955.                                         break;
  1956.                                     case 'l':
  1957.                                         (void) fprintf(stderr,
  1958.                          "            DINO number the lines of the program listing\n");
  1959.                                         break;
  1960.                                     case 'n':
  1961.                                         (void) fprintf(stderr,
  1962.                                    "            DINO compiler notes will be printed\n");
  1963.                                         break;
  1964.                                     case 'o':
  1965.                                         (void) fprintf(stderr,
  1966.                                     "            DINO will use the old suffix model\n");
  1967.                                         break;
  1968.                                     case 'w':
  1969.                                         (void) fprintf(stderr,
  1970.                             "            DINO compiler warnings will not be printed\n");
  1971.                                         break;
  1972.                                     case 'Q':
  1973.                                         (void) fprintf(stderr,
  1974.                                 "            DINO will run in quiet mode\n");
  1975.                                         break;
  1976.                                    }
  1977.                                }
  1978.                            }
  1979.                        }
  1980.                     (void) fprintf(stderr,
  1981.                                     "\n    The system default machine is %s\n\n",
  1982.                                                     machines[default_mach].name);
  1983.                     (void) printf("quit\n");
  1984.                     exit(0);
  1985.                     break;
  1986.                  case 'H':
  1987.                     if (option[2] == '\0' || (strcmp(&(option[1]), "HELP") == 0))
  1988.                        {
  1989.                         dmessage();
  1990.                         (void) printf("quit");
  1991.                         exit(0);
  1992.                        }
  1993.                     else
  1994.                         error(1, "\tNon-existent DINO option: %s\n", argv[I]);
  1995.                     break;
  1996.                 case 'I':
  1997.                     if (option[2] == '\0')
  1998.                        {
  1999.                         if (I + 1 < argc && argv[I+1][0] != '-')
  2000.                            {
  2001.                             if (stat(argv[I+1], &buf1) != 0)
  2002.                                {
  2003.                                 error(0,
  2004.                                     "\tUnable to access include directory %s\n",
  2005.                                                                       argv[I+1]);
  2006.                                }
  2007.                             else
  2008.                                {
  2009.                                 if (NINC < MAXINCLUDE)
  2010.                                    {
  2011.                                     (void) strcpy(INCLUDE[NINC++], argv[I+1]);
  2012.                                     I++;
  2013.                                    }
  2014.                                 else
  2015.                                     error(0,
  2016.                       "\tMaximun number of include directories (%d) exceeded.\n",
  2017.                                                                    MAXINCLUDE-1);
  2018.                                }
  2019.                            }
  2020.                         else
  2021.                            {
  2022.                             error(0, "\tMissing argument to DINO option: %s\n",
  2023.                                                                         argv[I]);
  2024.                            }
  2025.                        }
  2026.                     else
  2027.                        {
  2028.                         if (stat(&(option[2]), &buf1) != 0)
  2029.                            {
  2030.                             error(0, "\tUnable to access include directory %s\n",
  2031.                                                                   &(argv[I][2]));
  2032.                            }
  2033.                         else
  2034.                            {
  2035.                             if (NINC < MAXINCLUDE)
  2036.                                 (void) strcpy(INCLUDE[NINC++], &(argv[I][2]));
  2037.                             else
  2038.                                 error(0,
  2039.                       "\tMaximun number of include directories (%d) exceeded.\n",
  2040.                                                                  MAXINCLUDE-1);
  2041.                            }
  2042.  
  2043.                        }
  2044.                     break;
  2045.                 case 'L':
  2046.                     if (option[2] == '\0')
  2047.                        {
  2048.                         if (I + 1 >= argc || argv[I+1][0] == '-' ||
  2049.                                  (LASTTYPE = strtol(argv[I+1], &temp, 0)) == 0 ||
  2050.                                                                 temp[0] != '\0')
  2051.                            {
  2052.                             if (I + 1 >= argc || argv[I+1][0] == '-')
  2053.                                 error(0, "\tMissing argument to DINO option: %s\n",
  2054.                                                                         argv[I]);
  2055.                             else
  2056.                                 error(0,
  2057.                                     "\tInvalid argument to DINO option: %s %s\n",
  2058.                                                               argv[I], argv[I+1]);
  2059.                            }
  2060.                        }
  2061.                     else
  2062.                         if ((LASTTYPE = strtol(&(option[2]), &temp, 0)) == 0 ||
  2063.                                                                 temp[0] != '\0')
  2064.                             error(0, "\tInvalid argument to DINO option: %s\n",
  2065.                                                                         argv[I]);
  2066.                     break;
  2067.                 case 'M':
  2068.                     MODEL = TRUE;
  2069.                     if (option[2] == '\0')
  2070.                        {
  2071.                         if (I + 1 < argc && argv[I+1][0] != '-')
  2072.                            {
  2073.                             switch (argv[I+1][0])
  2074.                                {
  2075.                                 case 's':
  2076.                                     TYPE = 's';
  2077.                                     break;
  2078.                                 case 'c':
  2079.                                     TYPE = 'c';
  2080.                                     break;
  2081.                                 default:
  2082.                                     error(0,
  2083.                         "\tIncorrect argument to DINO Model option: %s %s\n",
  2084.                                                             argv[I], argv[I+1]);
  2085.                                }
  2086.                             if (argv[I+1][1] == '\0')
  2087.                                {
  2088.                                 if (I + 2 < argc && argv[I+2][0] != '-')
  2089.                                    {
  2090.                                     switch (argv[I+1][1])
  2091.                                        {
  2092.                                         case '1':
  2093.                                             SERIES = '1';
  2094.                                             break;
  2095.                                         case '2':
  2096.                                             SERIES = '2';
  2097.                                             break;
  2098.                                         default:
  2099.                                             error(0,
  2100.                         "\tIncorrect argument to DINO Model option: %s %s\n",
  2101.                                                             argv[I], argv[I+1]);
  2102.  
  2103.                                        }
  2104.                                    }
  2105.                                 else
  2106.                                     error(0,
  2107.                                         "\tMissing argument to DINO option: %s\n",
  2108.                                                                         argv[I]);
  2109.                                 if (argv[I+1][2] != '\0')
  2110.                                     error(0,
  2111.                         "\tIncorrect argument to DINO Model option: %s %s\n",
  2112.                                                             argv[I], argv[I+1]);
  2113.                                 I++;
  2114.                                }
  2115.                             else
  2116.                                {
  2117.                                 switch (argv[I+1][1])
  2118.                                    {
  2119.                                     case '1':
  2120.                                         SERIES = '1';
  2121.                                         break;
  2122.                                     case '2':
  2123.                                         SERIES = '2';
  2124.                                         break;
  2125.                                     default:
  2126.                                         error(0,
  2127.                         "\tIncorrect argument to DINO Model option: %s %s\n",
  2128.                                                             argv[I], argv[I+1]);
  2129.                                    }
  2130.                             if (argv[I+1][2] != '\0')
  2131.                                 error(0,
  2132.                         "\tIncorrect argument to DINO Model option: %s %s\n",
  2133.                                                             argv[I], argv[I+1]);
  2134.                                }
  2135.                            }
  2136.                         else
  2137.                             error(0,
  2138.                                 "\tMissing argument to DINO Model option: %s\n",
  2139.                                                                         argv[I]);
  2140.                         I++;
  2141.                        }
  2142.                     else
  2143.                        {
  2144.                         switch (option[2])
  2145.                            {
  2146.                             case 's':
  2147.                                 TYPE = 's';
  2148.                                 break;
  2149.                             case 'c':
  2150.                                 TYPE = 'c';
  2151.                                 break;
  2152.                             default:
  2153.                                 error(0,
  2154.                             "\tIncorrect argument to DINO Model option: %s\n",
  2155.                                                                         argv[I]);
  2156.                            }
  2157.                         if (option[3] == '\0')
  2158.                            {
  2159.                             if (I + 1 < argc && argv[I+1][0] != '-')
  2160.                                {
  2161.                                 switch (argv[I+1][1])
  2162.                                    {
  2163.                                     case '1':
  2164.                                         SERIES = '1';
  2165.                                         break;
  2166.                                     case '2':
  2167.                                         SERIES = '2';
  2168.                                         break;
  2169.                                     default:
  2170.                                         error(0,
  2171.                         "\tIncorrect argument to DINO Model option: %s %s\n",
  2172.                                                             argv[I], argv[I+1]);
  2173.                                    }
  2174.                                 I++;
  2175.                                }
  2176.                             else
  2177.                                 error(0,
  2178.                                 "\tMissing argument to DINO Model option: %s\n",
  2179.                                                                         argv[I]);
  2180.                            }
  2181.                         else
  2182.                            {
  2183.                             switch (option[3])
  2184.                                {
  2185.                                 case '1':
  2186.                                     SERIES = '1';
  2187.                                     break;
  2188.                                 case '2':
  2189.                                     SERIES = '2';
  2190.                                     break;
  2191.                                 default:
  2192.                                     error(0,
  2193.                             "\tIncorrect argument to DINO Model option: %s\n",
  2194.                                                                         argv[I]);
  2195.                                }
  2196.                             if (option[4] != '\0')
  2197.                                 error(0,
  2198.                             "\tIncorrect argument to DINO Model option: %s\n",
  2199.                                                                         argv[I]);
  2200.                            }
  2201.                        }
  2202.                     break;
  2203.                 case 'P':
  2204.                     if (option[2] == '\0')
  2205.                         output[count++] = 'P';
  2206.                     else
  2207.                         error(1, "\tNon-existent DINO option: %s\n", argv[I]);
  2208.                     break;
  2209.                 case 'Q':
  2210.                     if (option[2] == '\0')
  2211.                         output[count++] = 'Q';
  2212.                     else
  2213.                         error(1, "\tNon-existent DINO option: %s\n", argv[I]);
  2214.                     break;
  2215.                 case 'S':
  2216.                     if (option[2] == '\0')
  2217.                        {
  2218.                         if (I + 1 >= argc || argv[I+1][0] == '-' ||
  2219.                                  (FIRSTTYPE = strtol(argv[I+1], &temp, 0)) == 0 ||
  2220.                                                                 temp[0] != '\0')
  2221.                            {
  2222.                             if (I + 1 >= argc || argv[I+1][0] == '-')
  2223.                                 error(0, "\tMissing argument to DINO option: %s\n",
  2224.                                                                         argv[I]);
  2225.                             else
  2226.                                 error(0,
  2227.                                     "\tInvalid argument to DINO option: %s %s\n",
  2228.                                                               argv[I], argv[I+1]);
  2229.                            }
  2230.                        }
  2231.                     else
  2232.                         if ((FIRSTTYPE = strtol(&(option[2]), &temp, 0)) == 0 ||
  2233.                                                                 temp[0] != '\0')
  2234.                             error(0, "\tInvalid argument to DINO option: %s\n",
  2235.                                                                         argv[I]);
  2236.                     break;
  2237.                 default:
  2238.                     if (! macherr)
  2239.                         error(1, "\tNon-existent DINO option: %s\n", argv[I]);
  2240.                     else
  2241.                         error(2,
  2242.                             "\tUnknown DINO option: %s. Continuing anyway.\n",
  2243.                                                                         argv[I]);
  2244.                }
  2245.            }
  2246.         else
  2247.            {
  2248.             if (found)
  2249.                {
  2250.                 error(0,
  2251.                 "\tMore than one DINO source file specified:\n\t\t%s\n\t\t%s\n",
  2252.                                                               SOURCE, argv[I]);
  2253.                }
  2254.             else
  2255.                {
  2256.                 if (stat(argv[I], &buf1) != 0)
  2257.                     error(0, "\tUnable to access DINO source file %s.\n",
  2258.                                                                      argv[I]);
  2259.                 else
  2260.                    {
  2261.                     (void) strcpy(SOURCE, argv[I]);
  2262.                     found = TRUE;
  2263.                    }
  2264.                }
  2265.            }
  2266.        }
  2267.    }
  2268.  
  2269. static void addbools(input, shell)
  2270.     char *input;
  2271.     BOOL shell;
  2272.    {
  2273.     int I;
  2274.     BOOL value = TRUE;
  2275.  
  2276.     for (I = 0; input[I] != '\0'; I++)
  2277.        {
  2278.         if (input[I] == '^')
  2279.            {
  2280.             value = FALSE;
  2281.             continue;
  2282.            }
  2283.         switch (input[I])
  2284.            {
  2285.             case 'a':
  2286.                 ALADIN = value;
  2287.                 break;
  2288.             case 'c':
  2289.                 COMMENTS = value;
  2290.                 break;
  2291.             case 'e':
  2292.                 ORDER = value;
  2293.                 break;
  2294.             case 'l':
  2295.                 NUMBERS = value;
  2296.                 break;
  2297.             case 'n':
  2298.                 NOTES = value;
  2299.                 break;
  2300.             case 'o':
  2301.                 SUFFIX_MODEL = ! value;
  2302.                 break;
  2303.             case 'p':
  2304.                 if (shell)
  2305.                    {
  2306.                     error(0, "\tInvalid option \"p\" in sD%sopt\n",
  2307.                                                  machines[default_mach].name);
  2308.                    }
  2309.                 else
  2310.                    {
  2311.                     if (value)
  2312.                         PARTIAL = 1;
  2313.                     else
  2314.                         PARTIAL = 2;
  2315.                    }
  2316.                 break;
  2317.             case 'w':
  2318.                 WARNINGS = value;
  2319.                 break;
  2320.             case 'P':
  2321.                 if (shell)
  2322.                    {
  2323.                     error(0, "\tInvalid option \"P\" in sD%sopt\n",
  2324.                                                     machines[default_mach].name);
  2325.                    }
  2326.                 else
  2327.                    {
  2328.                     if (value)
  2329.                         PARTIAL = 0;
  2330.                     else
  2331.                         PARTIAL = 2;
  2332.                    }
  2333.                 break;
  2334.             case 'Q':
  2335.                 QUIET = value;
  2336.                 break;
  2337.             default:
  2338.                 if (shell)
  2339.                     error(0,
  2340.                         "\tInvalid system option \"%c\" provided in sD%sopt\n",
  2341.                                         input[I], machines[default_mach].name);
  2342.                 else
  2343.                     error(0,
  2344.                            "\tInvalid user option \"%c\" provided in D%sopt\n",
  2345.                                         input[I], machines[default_mach].name);
  2346.            }
  2347.         value = TRUE;
  2348.        }
  2349.    }
  2350.